"""
AI对话服务
"""
import json
from typing import List, Dict, Optional, Tuple
from openai import OpenAI
from loguru import logger
from sqlalchemy.orm import Session

from app.core.config import settings
from app.models.session import ChatSession, ChatMessage, MessageType
from app.services.knowledge_service import KnowledgeService


class AIService:
    """AI对话服务"""
    
    def __init__(self):
        # 检查API密钥配置
        if not settings.openai_api_key:
            logger.warning("⚠️  OpenAI API密钥未配置，AI功能将不可用")
            self.client = None
        else:
            try:
                self.client = OpenAI(
                    api_key=settings.openai_api_key,
                    base_url=settings.openai_base_url
                )
                logger.info("✅ OpenAI客户端初始化成功")
            except Exception as e:
                logger.error(f"❌ OpenAI客户端初始化失败: {e}")
                self.client = None

        self.knowledge_service = KnowledgeService()
        
        # 系统提示词
        self.system_prompt = """你是XX银行零售贷款系统操作助手，专门基于XX银行零售贷款系统操作手册V1.1回答问题。

回答原则：
1. 优先使用提供的相关文档内容回答问题
2. 如果相关文档中有答案，直接基于文档内容回答，包括具体的操作步骤
3. 仔细分析所有提供的文档片段，即使相似度较低，只要内容相关就要使用
4. 只有在所有文档片段都完全不相关时，才回答"操作手册中未找到相关信息"
5. 对于部分相关的内容，可以基于现有信息给出有用的回答，并说明信息来源
6. 必须包含文档中的安全警告和注意事项
7. 回答要具体、准确，避免模糊表述
8. 重点关注银行业务操作流程、系统功能使用、风险控制等内容

特别注意：
- 用户查询可能包含"如何"、"怎么"等疑问词，重点关注查询的核心主题
- 即使文档片段看起来相似度不高，但如果包含用户询问的核心概念，就应该使用
- 优先提取和使用文档中的具体操作步骤和系统功能说明
- 对于银行业务操作，要特别注意权限要求、风险等级和操作规范"""
    
    async def generate_response(
        self,
        db: Session,
        session_id: str,
        user_message: str,
        system_context: Optional[Dict] = None
    ) -> Tuple[str, float, Optional[int]]:
        """生成AI回复"""
        try:
            # 检查OpenAI客户端是否可用
            if not self.client:
                return (
                    "抱歉，AI服务当前不可用。请检查API密钥配置。\n\n"
                    "配置步骤：\n"
                    "1. 复制 .env.example 为 .env\n"
                    "2. 在 .env 文件中设置 OPENAI_API_KEY\n"
                    "3. 重启服务",
                    0.0,
                    None
                )
            # 搜索相关知识
            relevant_docs = self.knowledge_service.search_documents(
                query=user_message,
                platform=system_context.get("platform") if system_context else None
            )

            # 构建上下文
            context = self._build_context(relevant_docs, system_context)
            
            # 获取历史对话
            chat_session = db.query(ChatSession).filter(
                ChatSession.session_id == session_id
            ).first()
            
            history_messages = []
            if chat_session:
                recent_messages = db.query(ChatMessage).filter(
                    ChatMessage.session_id == chat_session.id
                ).order_by(ChatMessage.created_at.desc()).limit(10).all()
                
                history_messages = [
                    {
                        "role": msg.message_type.value,
                        "content": msg.content
                    }
                    for msg in reversed(recent_messages)
                ]
            
            # 构建消息列表
            messages = [
                {"role": "system", "content": self.system_prompt},
                {"role": "system", "content": f"上下文信息：\n{context}"}
            ]
            
            # 添加历史对话（最近5轮）
            messages.extend(history_messages[-10:])
            
            # 添加当前用户消息
            messages.append({"role": "user", "content": user_message})

            # 打印最终发送给模型的提示词
            logger.info("=" * 80)
            logger.info("🤖 最终发送给模型的提示词:")
            logger.info("=" * 80)
            for i, message in enumerate(messages, 1):
                role = message["role"]
                content = message["content"]
                logger.info(f"消息 {i} [{role.upper()}]:")
                logger.info(f"{content}")
                logger.info("-" * 40)
            logger.info("=" * 80)

            # 调用OpenAI API
            response = self.client.chat.completions.create(
                model=settings.openai_model,
                messages=messages,
                temperature=0.7,
                max_tokens=2000
            )
            
            ai_response = response.choices[0].message.content
            confidence_score = self._calculate_confidence(response, relevant_docs)
            
            # 确定关联的操作文档ID
            operation_id = None
            if relevant_docs and relevant_docs[0]["similarity"] > -0.5:
                # 如果有相关度较高的文档，尝试找到对应的数据库记录
                # 这里需要根据实际情况实现
                pass
            
            logger.info(f"AI回复生成成功，置信度: {confidence_score}")
            return ai_response, confidence_score, operation_id
            
        except Exception as e:
            logger.error(f"生成AI回复失败: {e}")
            return "抱歉，我遇到了一些技术问题，请稍后再试。", 0.0, None
    
    def _build_context(
        self,
        relevant_docs: List[Dict],
        system_context: Optional[Dict]
    ) -> str:
        """构建上下文信息"""
        context_parts = []

        # 添加系统信息
        if system_context:
            context_parts.append("用户系统信息：")
            for key, value in system_context.items():
                context_parts.append(f"- {key}: {value}")
            context_parts.append("")

        # 添加相关文档
        if relevant_docs:
            context_parts.append("XX银行零售贷款系统操作手册相关内容：")
            for i, doc in enumerate(relevant_docs[:5], 1):  # 使用更多文档
                metadata = doc["metadata"]
                context_parts.append(f"\n文档片段 {i}:")
                context_parts.append(f"来源: {metadata.get('title', 'XX银行零售贷款系统操作手册')}")
                # 显示更多内容，不截断
                content = doc['content']
                if len(content) > 500:
                    context_parts.append(f"内容: {content[:500]}...")
                else:
                    context_parts.append(f"内容: {content}")
                context_parts.append("")
        
        return "\n".join(context_parts)
    
    def _calculate_confidence(self, response, relevant_docs: List[Dict]) -> float:
        """计算回答置信度"""
        base_confidence = 0.5

        # 根据相关文档的数量和相似度调整置信度
        if relevant_docs:
            max_similarity = max(doc["similarity"] for doc in relevant_docs)
            # 将负数相似度转换为正数置信度
            similarity_confidence = max(0, (max_similarity + 1) / 2)  # 将-1到1映射到0到1
            doc_count_factor = min(len(relevant_docs) / 3, 1.0)
            base_confidence += similarity_confidence * 0.3 + doc_count_factor * 0.2

        # 根据响应长度调整（过短或过长的回答可能置信度较低）
        response_length = len(response.choices[0].message.content)
        if 100 <= response_length <= 1500:
            base_confidence += 0.1

        return min(base_confidence, 1.0)

    async def summarize_conversation(self, db: Session, session_id: str) -> str:
        """总结对话内容"""
        try:
            chat_session = db.query(ChatSession).filter(
                ChatSession.session_id == session_id
            ).first()

            if not chat_session:
                return "未找到对话记录"

            messages = db.query(ChatMessage).filter(
                ChatMessage.session_id == chat_session.id
            ).order_by(ChatMessage.created_at).all()

            if not messages:
                return "对话为空"

            # 构建对话历史
            conversation = []
            for msg in messages:
                role = "用户" if msg.message_type == MessageType.USER else "助手"
                conversation.append(f"{role}: {msg.content}")

            conversation_text = "\n".join(conversation)

            # 生成总结
            summary_prompt = f"""请总结以下对话的主要内容和解决的问题：

{conversation_text}

请用简洁的语言总结：
1. 用户遇到的主要问题
2. 提供的解决方案
3. 关键操作步骤
"""

            response = self.client.chat.completions.create(
                model=settings.openai_model,
                messages=[{"role": "user", "content": summary_prompt}],
                temperature=0.3,
                max_tokens=500
            )

            return response.choices[0].message.content

        except Exception as e:
            logger.error(f"总结对话失败: {e}")
            return "总结生成失败"
